/*
 * TOP SECRET Copyright 2006-2015 Transsion.com All right reserved. This software is the confidential and proprietary
 * information of Transsion.com ("Confidential Information"). You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license agreement you entered into with Transsion.com.
 */
package com.yunji.framework_template.common.web;

/**
 * ClassName:Page <br/>
 * Date: 2018年10月22日 下午3:07:24 <br/>
 * 
 * @author fenglibin1982@163.com
 * @Blog http://blog.csdn.net/fenglibing
 * @version
 * @see
 */
public class Page<T> {

    /**
     * current request page
     */
    private long currentPage = 1;
    /**
     * current request page size
     */
    private long pageSize    = 15;
    /**
     * the start offset of the request record, this needed to be calculate by the page and rows
     */
    private long offset      = 0;
    /**
     * total pages of this request
     */
    private long totalPages  = 0;
    /**
     * total records of this records
     */
    private long totalCount  = 0;
    /**
     * thd search request obj which used for where condition
     */
    private T    obj;

    public Page(){

    }

    public Page(Page<?> page){
        this.currentPage = page.currentPage;
        this.offset = page.getOffset();
        this.pageSize = page.getPageSize();
        this.totalCount = page.getTotalCount();
        this.totalPages = page.getTotalPages();
    }

    public Page(Page<?> page, T t){
        this.currentPage = page.currentPage;
        this.offset = page.getOffset();
        this.pageSize = page.getPageSize();
        this.totalCount = page.getTotalCount();
        this.totalPages = page.getTotalPages();
        this.obj = t;
    }
    
    public Page(int currentPage){
        this.currentPage = currentPage;
    }
    
    public Page(int currentPage, int pageSize){
        this.currentPage = currentPage;
        this.pageSize = pageSize;
    }

    public long getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(long currentPage) {
        this.currentPage = currentPage;
    }

    public long getPageSize() {
        return pageSize;
    }

    public void setPageSize(long pageSize) {
        this.pageSize = pageSize;
    }

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }

    public long getOffset() {
        return offset;
    }

    public void setOffset(long offset) {
        this.offset = offset;
    }

    public long getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(long totalPages) {
        this.totalPages = totalPages;
    }

    public long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(long totalCount) {
        this.totalCount = totalCount;
    }

    /**
     * 根据总记录数、当前页及每页的大小，计算倒序显示记录的数据的偏移量，这样可以解决通过order by倒序显示数据增加数据库负担的问题<br>
     * 如满足要求的记录总数有405条，每页显示10条，则第一页取的数据就是从第396条开始取取到第406条数据，第二页从386条取到395条，其它依次类推。
     * 
     * @param totalCount 总记录数
     * @return 计算好的page结果
     */
    public Page<T> reverseDisplayCalculate(long totalCount) {
        return reverseDisplayCalculate(this.currentPage, totalCount);
    }

    /**
     * 根据总记录数、当前页及每页的大小，计算倒序显示记录的数据的偏移量，这样可以解决通过order by倒序显示数据增加数据库负担的问题<br>
     * 如满足要求的记录总数有405条，每页显示10条，则第一页取的数据就是从第396条开始取取到第406条数据，第二页从386条取到395条，其它依次类推。
     * 
     * @param currentPage 当前页
     * @param totalCount 总记录数
     * @return 计算好的page结果
     */
    public Page<T> reverseDisplayCalculate(long _currentPage, long _totalCount) {
        if (_totalCount == 0) {
            return this;
        }
        if (_currentPage < 1) {
            _currentPage = 1;
        }
        this.currentPage = _currentPage;
        this.totalCount = _totalCount;
        /**
         * Calculate total pages
         */
        long mod = this.totalCount % this.pageSize;
        this.totalPages = this.totalCount / this.pageSize;
        if (mod > 0) {
            this.totalPages++;
        }

        if (this.currentPage > this.totalPages) {// 如果当前页面大于了总页数，是查不出来数据的，如这里用户输入页码为4时，是不会有结果的，直接返回0记录
            this.offset = 0;
            this.pageSize = 0;
            this.totalPages = 0;
            this.totalCount = 0;
            return this;
        }

        this.offset = this.totalCount - this.currentPage * this.pageSize;
        if (offset < 0) {
            this.offset = 0;
        }

        if (this.offset == 0) {
            this.pageSize = this.totalCount - ((this.currentPage - 1) * this.pageSize);
        }
        return this;
    }

    /**
     * 根据总记录数、当前页及每页的大小，按查询到的结果得到顺序分页显示结果
     * 
     * @param totalCount 总记录数
     * @return
     */
    public Page<T> sequentialDisplayCalculate(long totalCount) {
        return sequentialDisplayCalculate(this.currentPage, totalCount);
    }

    /**
     * 根据总记录数、当前页及每页的大小，按查询到的结果得到顺序分页显示结果
     * 
     * @param currentPage 当前页
     * @param totalCount 总记录数
     * @return
     */
    public Page<T> sequentialDisplayCalculate(long _currentPage, long _totalCount) {
        if (_totalCount == 0) {
            return this;
        }
        if (_currentPage < 1) {
            _currentPage = 1;
        }
        this.currentPage = _currentPage;
        this.totalCount = _totalCount;
        /**
         * Calculate total pages
         */
        long mod = this.totalCount % this.pageSize;
        this.totalPages = this.totalCount / this.pageSize;
        if (mod > 0) {
            this.totalPages++;
        }

        if (this.currentPage > this.totalPages) {// 如果当前页面大于了总页数，是查不出来数据的，如这里用户输入页码为4时，是不会有结果的，直接返回0记录
            this.offset = 0;
            this.pageSize = 0;
            this.totalPages = 0;
            this.totalCount = 0;
            return this;
        }

        this.offset = (this.currentPage - 1) * this.pageSize;
        return this;
    }
}
